package cn.onein.edu.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import cn.onein.edu.common.ProductPeriodType;

/**
 * 日期、生日计算工具类
 * 
 * @author Upton
 * 
 */
public class DateUtil {
	
	private final static int ONE_WEEK_KEY = 7;
	
	private final static int ONE_MONTH_KEY = 1;
	
	private final static int ONE_QUARTER_KEY = 3;
	
	private final static int HALF_YEAR_KEY = 6;
	
	private final static int ONE_YEAR_KEY = 1;
	
	private final static int DOUBLE_YEAR_KEY = 2;

	/**
	 * 根据生日计算年龄，如果是预产期则返回-1,如果0=<birthday<1算0岁，1=<birthday<2算1岁
	 * 
	 * @param birthday
	 *            生日
	 * @return 年龄
	 */
	public static int birthday2Age(Date birthday) {
		return birthday2Age(birthday, new Date());
	}

	/**
	 * 根据生日计算年龄，如果是预产期则返回-1,如果0=<birthday<1算0岁，1=<birthday<2算1岁
	 * 
	 * @param birthday
	 *            生日
	 * @param precessDay
	 *            处理计算的日期
	 * @return 年龄
	 */
	public static int birthday2Age(Date birthday, Date precessDay) {
		if (birthday == null) {
			throw new IllegalArgumentException(
					"The birthday must be not null in DateUtil.birthday2Age(Date birthday)");
		}

		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		Date today = precessDay;
		try {
			birthday = format.parse(format.format(birthday));
			today = format.parse(format.format(today));
		} catch (ParseException e) {
			throw new RuntimeException(
					"Pasre date error in DateUtil.birthday2Age(Date birthday)");
		}

		Calendar birthCal = Calendar.getInstance();
		Calendar todayCal = Calendar.getInstance();

		birthCal.setTime(birthday);
		todayCal.setTime(today);

		if (todayCal.before(birthCal)) {
			// 孕产期时间，返回-1
			return -1;
		} else {
			// 孩子的年龄
			int birthYear = birthCal.get(Calendar.YEAR);
			int todayYear = todayCal.get(Calendar.YEAR);

			int birthMonth = birthCal.get(Calendar.MONTH);
			int todayMonth = todayCal.get(Calendar.MONTH);

			int birthDayOfMonth = birthCal.get(Calendar.DAY_OF_MONTH);
			int todayDayOfMonth = todayCal.get(Calendar.DAY_OF_MONTH);

			int age = todayYear - birthYear;
			if (todayMonth <= birthMonth) {
				if (todayMonth == birthMonth) {
					// monthNow==monthBirth
					if (todayDayOfMonth < birthDayOfMonth) {
						age--;
					} else {
						// do nothing
					}
				} else {
					// monthNow>monthBirth
					age--;
				}
			} else {
				// monthNow<monthBirth
				// donothing
			}

			return age;
		}
	}

	/**
	 * 通过怀孕周得到孩子生日
	 * 
	 * @param weeks
	 * @return date 孩子生日
	 */
	public static Date getDateByWeeks(int weeks) {
		int days = (40 - weeks) * 7;
		Date nowDate = new Date();
		Calendar cl = Calendar.getInstance();
		cl.setTime(nowDate);
		cl.add(Calendar.DATE, days);
		return cl.getTime();
	}

	/**
	 * 得到给定日期相隔天数后日期
	 * 
	 * @param days
	 *            相隔天数
	 * @return date 计算日期
	 */
	public static Date getDateBydays(Date currDate, int days) {
		Calendar cl = Calendar.getInstance();
		cl.setTime(currDate);
		cl.add(Calendar.DATE, days);
		return cl.getTime();
	}

	/**
	 * 根据生日计算指定日期对应的DailAction的顺序,从0开始
	 * 
	 * @param birthday
	 *            生日
	 * @param precessDay
	 *            指定处理日期
	 * @return DailAction的顺序编号
	 */
	public static int calcActionIndexByBirthday(Date birthday, Date precessDay) {
		if (birthday == null || precessDay == null) {
			throw new IllegalArgumentException(
					"The birthday & precessDay must be not null in DateUtil.calcActionIndexByBirthday.");
		}

		if (birthday.after(precessDay)) {
			throw new IllegalArgumentException(
					"The birthday must befer precessDay in DateUtil.calcActionIndexByBirthday.");
		}

		int result = 0;

		Calendar birthCal = Calendar.getInstance();
		birthCal.setTime(birthday);

		Calendar precessCal = Calendar.getInstance();
		precessCal.setTime(precessDay);

		int birthDayOfYear = birthCal.get(Calendar.DAY_OF_YEAR);
		int precessDayOfYear = precessCal.get(Calendar.DAY_OF_YEAR);

		result = precessDayOfYear - birthDayOfYear;
		if (result < 0) {
			Date now = new Date();
			Calendar temp = Calendar.getInstance();
			temp.setTime(now);
			temp.add(Calendar.YEAR, -1);

			Calendar lastYearCal = Calendar.getInstance();

			// 去年的最后一天
			lastYearCal.set(temp.get(Calendar.YEAR), 11, 31);

			int lastYearDayOfYear = lastYearCal.get(Calendar.DAY_OF_YEAR);

			result = (lastYearDayOfYear - birthDayOfYear) + precessDayOfYear;
		}

		return result;
	}

	public static String mailDispDateStr(Date date) {
		if (date == null) {
			throw new IllegalArgumentException(
					"The date must be not null in DateUtil.mailDispDateStr.");
		}

		SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 ");
		String week = "";

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		switch (cal.get(Calendar.DAY_OF_WEEK)) {
		case 1:
			week = "星期日";
			break;
		case 2:
			week = "星期一";
			break;
		case 3:
			week = "星期二";
			break;
		case 4:
			week = "星期三";
			break;
		case 5:
			week = "星期四";
			break;
		case 6:
			week = "星期五";
			break;
		case 7:
			week = "星期六";
			break;
		default:
			break;
		}

		return format.format(date) + week;
	}

	/**
	 * 转换Date为SQL查询字符串参数，输出格式为yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 */
	public static String formatDate4Query(Date date) {
		if (date == null) {
			throw new IllegalArgumentException(
					"The date must be not null in DateUtil.formatDate4Query.");
		}

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

		return format.format(date);
	}

	/**
	 * 根据日期取得中文的周几
	 * 
	 * @param dt
	 * @return
	 */
	public static String getWeekOfDate(Date dt) {
		String[] weekDays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
		String today = "今天";
		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);

		Calendar calToday = Calendar.getInstance();
		if(cal.get(Calendar.YEAR) == calToday.get(Calendar.YEAR) &&
		   cal.get(Calendar.MONTH) == calToday.get(Calendar.MONTH) &&
		   cal.get(Calendar.DAY_OF_MONTH) == calToday.get(Calendar.DAY_OF_MONTH)){
			return today;
		}
		
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		
		if (w < 0){
			w = 0;
		}

		return weekDays[w];
	}

	/**
	 * 计算两个日期间隔天数
	 * 
	 * @param firstDate
	 *            开始日期
	 * @param secondDate
	 *            结束日期
	 * @return 返回间隔天数
	 */
	public static int daysOfTwo(Date firstDate, Date secondDate) {
		Calendar aCalendar = Calendar.getInstance();
		
		aCalendar.setTime(firstDate);
		int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
		
		aCalendar.setTime(secondDate);
		int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
		
		// 求出两日期相隔天数
		int days = day2 - day1;
		
		return days;
	}

	public static void main(String[] args) throws Exception {

		Date birthday = new SimpleDateFormat("yyyyMMdd").parse("20101121");

		Date preccessday = new SimpleDateFormat("yyyyMMdd").parse("20111105");

		SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
		System.out.println(mailDispDateStr(birthday));
	}
	
	public static Date getDateByPeriod(Date date,ProductPeriodType period){
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		
		if(ProductPeriodType.Week == period){
			cl.add(Calendar.DATE, ONE_WEEK_KEY);
			return cl.getTime();
		}
		
		if(ProductPeriodType.Month == period){
			cl.add(Calendar.MONTH, ONE_MONTH_KEY );
			return cl.getTime();
		}
		
		if(ProductPeriodType.Quarter == period){
			cl.add(Calendar.MONTH, ONE_QUARTER_KEY );
			return cl.getTime();
		}
		
		if(ProductPeriodType.HalfYear == period){
			cl.add(Calendar.MONTH, HALF_YEAR_KEY );
			return cl.getTime();
		}
		
		if(ProductPeriodType.Year == period){
			cl.add(Calendar.YEAR, ONE_YEAR_KEY );
			return cl.getTime();
		}
		
		if(ProductPeriodType.DoubleYear == period){
			cl.add(Calendar.YEAR, DOUBLE_YEAR_KEY );
			return cl.getTime();
		}
		
		return null;
	}

}
